package units

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"math/rand"
	"net"
	"reflect"
	"strings"
	"time"
	"unsafe"
)

func GetLocalIP() string {
	adders, err := net.InterfaceAddrs()
	if err != nil {
		return ""
	}

	for _, address := range adders {
		// 检查ip地址判断是否回环地址
		if inept, ok := address.(*net.IPNet); ok && !inept.IP.IsLoopback() {
			if inept.IP.To4() != nil {
				return inept.IP.String()
			}
		}
	}
	return "127.0.0.1"
}

func LocalIp(c *gin.Context) string {
	/*	resp, err := http.Get("https://www.taobao.com/help/getip.php")
		if err != nil {
			return "127.0.0.1"
		}
		defer resp.Body.Close()
		body, _ := ioutil.ReadAll(resp.Body)
		clientIP := fmt.Sprintf("%s", string(body))
		// println("===============", clientIP)
		arr := strings.Split(clientIP, "\"")*/
	return c.ClientIP()
}

func ReplaceSpace(str string) string {
	//最后一个参数为替换次数，负数表示没有次数限制
	str = strings.Replace(str, " ", "%20", -1)
	return str
}

type MyClaims struct {
	Username string `json:"username`
	jwt.StandardClaims
}

var StartTime = time.Now().Unix() - 60 //当前时间一分钟前生效
var EndTime = time.Now().Unix() + 60   //两个小时失效
var IssUer = "zyzhan"                  //签发者
var JwtEy = []byte("hello")            //生成结构体的私钥 key

// TokenEncrypt 加密
func TokenEncrypt(user string) string {
	c := MyClaims{
		Username: user,
		StandardClaims: jwt.StandardClaims{
			NotBefore: StartTime,
			ExpiresAt: EndTime,
			Issuer:    IssUer,
		},
	}
	// 使用指定的签名方法创建签名对象
	t := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	//该方法内部生成签名字符串，再用于获取完整、已签名的token
	s, err := t.SignedString(JwtEy)
	if err != nil {
		fmt.Printf("err: %v\n", err)
	}
	return s
}

// TokenDecrypt 解密
func TokenDecrypt(tokenString string) string {
	// s := TokenEncrypt(User_Input)
	mySigningKey := &MyClaims{}
	token, _ := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(t *jwt.Token) (interface{}, error) {
		return mySigningKey, nil
	})
	// fmt.Printf("token: %v\n", token)
	// fmt.Printf("err: %v\n", err)
	fmt.Printf("token.Claims: %v\n", token.Claims.(*MyClaims).Username)
	return token.Claims.(*MyClaims).Username
}

type UserType struct {
	User     string `json:"user"`
	Password string `json:"password"`
}

// Base64ToJson 解BASE64
func Base64ToJson(str string) UserType {
	//	jsonStr := `{\"user\":\"zyzhan\",\"password\":\"123456\"}`
	var p UserType
	decodeDataByteArr, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		return UserType{}
	}
	err = json.Unmarshal(decodeDataByteArr, &p)
	return p
}

// JsonToBase64 加密base64
func JsonToBase64(str string) string {
	return base64.StdEncoding.EncodeToString([]byte(str))
}

// RandomString 随机生成字符串
func RandomString(l int) string {
	str := "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
	bytes := []byte(str)
	var result []byte = make([]byte, 0, l)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < l; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return BytesToString(result)
}

// SetUserFive 用户账号截取五位
func SetUserFive(UserName string) string {
	if len(UserName) < 5 {
		return "error"
	}
	return UserName[0:5]
}

// GetTimeString 获取日期字符串
func GetTimeString() string {
	timestamp := time.Now().Unix()
	tm := time.Unix(timestamp, 0).Format("20060102150405")
	return tm
}

// BytesToString 0 拷贝转换 slice byte 为 string
func BytesToString(b []byte) (s string) {
	_bptr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	_sptr := (*reflect.StringHeader)(unsafe.Pointer(&s))
	_sptr.Data = _bptr.Data
	_sptr.Len = _bptr.Len
	return s
}
func MapToJson(param map[string]interface{}) string {
	dataType, _ := json.Marshal(param)
	dataString := string(dataType)
	return dataString
}
